import ddf.minim.*;

Minim minim;
AudioInput in;
int sampleCounter = 0;
float totalLoudness = 0.0;
float loudness = 0.0;
float soundCalibrationValue = 0.0;
float currentSoundCalibrationTime = 0.0;

void setupSoundDetection() {

  minim = new Minim(this);
  in = minim.getLineIn(Minim.STEREO, 512);
}

void handleSoundDetection() {
  //stroke(255);
  loudness = 0;
  for(int i = 0; i < in.bufferSize() - 1; i++) {
    loudness += abs(in.left.get(i));
    //graphical visualization
    //line(i, 50 + in.left.get(i)*50, i+1, 50 + in.left.get(i+1)*50);
    //line(i, 150 + in.right.get(i)*50, i+1, 150 + in.right.get(i+1)*50);
  } 
  loudness = loudness/in.bufferSize();
  totalLoudness += loudness;
  sampleCounter++;
}

void soundDetectionCalibration() {
  if(state != RatingImage) {
    currentSoundCalibrationTime += dt;

    if(currentSoundCalibrationTime >= CALIBRATION_TIME) {
      if(soundCalibrationValue < CALIBRATION_UPPER_LIMIT) {
        soundCalibrationValue = totalLoudness/sampleCounter;
      }
      else {
        soundCalibrationValue = CALIBRATION_UPPER_LIMIT;
      }
      currentSoundCalibrationTime = 0;
      totalLoudness = 0.0;
      sampleCounter = 0;
    }
  }
}


void stopSoundDetection() {
  in.close();
  minim.stop();
}

void startSoundDetectionRating() {
  totalLoudness = 0.0;
  sampleCounter = 0;
}


float getSoundDetectionRating() {
  
  if((totalLoudness/sampleCounter) > soundCalibrationValue) {
    float rawLoudnessScore = (((totalLoudness/sampleCounter) - soundCalibrationValue)/(1 - soundCalibrationValue));
    float loudnessScore = ceil(map(rawLoudnessScore, 0, RAW_HIGH_LOUDNESS_SCORE, LOW_SCORE, HIGH_SCORE));
    soundCalibrationValue = 0;
     if(loudnessScore > HIGH_SCORE) {
      return HIGH_SCORE;
    }

    return loudnessScore;
  }
  else {
    soundCalibrationValue = 0;
    return LOW_SCORE;
  }
}
